//
//  UICollectionViewSectionColorFlowLayout.swift
//  JLCloud
//
//  Created by zhangshumeng on 2020/11/4.
//

import UIKit

@objc protocol UICollectionViewSectionColorDelegateFlowLayout: UICollectionViewDelegateFlowLayout {
    
    @objc optional func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, backgroundColor section: Int) -> UIColor
}

class UICollectionViewSectionColorFlowLayout: UICollectionViewFlowLayout {

    var decorationViewAttrs = [UICollectionViewSectionColorLayoutAttributes]()
    
    override func prepare() {
        super.prepare()
        
        guard let collectionView = collectionView else {
            return
        }
        let numberOfSections = collectionView.numberOfSections
        if numberOfSections == 0 {
            return
        }
        register(UICollectionViewSectionColorReusableView.self, forDecorationViewOfKind: "UICollectionViewSectionColorReusableView")
        if !decorationViewAttrs.isEmpty {
            decorationViewAttrs.removeAll()
        }
        
        for index in 0..<numberOfSections {
            let numberOfItems = collectionView.numberOfItems(inSection: index)
            
            if numberOfItems == 0 {
                continue
            }
            if let delegate = collectionView.delegate, !delegate.conforms(to: UICollectionViewSectionColorDelegateFlowLayout.self) {
                continue
            }
            guard let firstAttr = layoutAttributesForItem(at: IndexPath(row: 0, section: index)), let lastAttr = layoutAttributesForItem(at: IndexPath(row: numberOfItems - 1, section: index)) else {
                continue
            }
            var sectionFrame = firstAttr.frame.union(lastAttr.frame)
            sectionFrame.origin.x -= sectionInset.left
            sectionFrame.origin.y -= sectionInset.top
            
            if scrollDirection == .horizontal {
                sectionFrame.size.width += (sectionInset.left + sectionInset.right)
                sectionFrame.size.height = collectionView.frame.size.height
            } else {
                sectionFrame.size.width = collectionView.frame.size.width
                sectionFrame.size.height += (sectionInset.top + sectionInset.bottom)
            }
            
            let decorationAtt = UICollectionViewSectionColorLayoutAttributes(forDecorationViewOfKind: "UICollectionViewSectionColorReusableView", with: IndexPath(row: 0, section: index))
            decorationAtt.frame = sectionFrame
            decorationAtt.zIndex = -1
            var sectionBgColor: UIColor? = nil
            if let delegate = collectionView.delegate as? UICollectionViewSectionColorDelegateFlowLayout {
                sectionBgColor = delegate.collectionView?(collectionView, layout: self, backgroundColor: index)
            }
            decorationAtt.sectionBgColor = sectionBgColor;
            decorationViewAttrs.append(decorationAtt)
        }
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }
        var allAttributes = [UICollectionViewLayoutAttributes]()
        allAttributes.append(contentsOf: attributes)
        for att in decorationViewAttrs {
            if rect.intersects(att.frame) {
                allAttributes.append(att)
            }
        }
        return allAttributes
    }

}

// UICollectionViewSectionColorLayoutAttributes
class UICollectionViewSectionColorLayoutAttributes: UICollectionViewLayoutAttributes {
    
    var sectionBgColor: UIColor?
}

// UICollectionViewSectionColorReusableView
class UICollectionViewSectionColorReusableView: UICollectionReusableView {
    override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
        super.apply(layoutAttributes)
        if let att = layoutAttributes as? UICollectionViewSectionColorLayoutAttributes {
            backgroundColor = att.sectionBgColor
        }
    }
}
